Domain-specific languages simplify programming by allowing programmers to develop applications in terms of abstractions relevant to particular domains. It is often advantageous to construct domain-specific languages as extensions to a base language, such as Java, C, and others. By doing so, programmers can reuse knowledge of the base language as well as existing code artifacts, such as libraries, for those languages. For the portions of the program that pertain to the domain, they can use the language extensions for that particular domain.
For example, the XJ language was developed by IBM for the integration of XML as a first-class construct into Java. XJ conforms to XML standards (XML Schema, Namespaces, XPath, XML 1.0) and is a strict extension of Java 1.4. By integrating XML constructs into the language, programmers can develop efficient, robust XML processing applications more intuitively than can be done using Java alone. While programmers can use XML-based constructs (such as XPath expressions) in developing an application, the compiler converts these constructs into standard Java byte codes that can execute on any Java Virtual Machine (JVM). Thus, a programmer has the advantage of the abstractions provided by XJ at the source level, while retaining the portability of Java at the execution level.
The XJ language allows programmers to distinguish XML data from non-XML data through type annotations on variables, methods, and expressions. The compiler recognizes the XML type system: it ensures that accesses to XML data and expressions are correct with respect to the XML Schema rules that govern the use of data annotated as being XML. To guarantee execution of XJ programs on standard virtual machines, however, the compiler generates pure Java byte code when compiling an XJ source file; thus, the generated code contains no XML type annotations. When, subsequently, one wishes to compile another XJ source file that refers to XML types used in the object code version of an XJ source file, an ordinary compiler would not have sufficient information to verify that the accesses in the XJ source file are correct with respect to the XML type system: the object code version has lost the necessary XML type annotations. Currently there is no straightforward way to record in compiled object code, the connection between the logical types (XML) and the concrete types (i.e., Java objects) so that a compiler may retain this information when another class is compiled against this object code. Supporting the separate compilation of XJ source files is an important issue since one would often wish to compile source files when they refer to types or methods used in code for which the source is not longer available (for example, library routines).
If one wants to extend the XJ compiler with mechanisms to handle other type systems, for example, to support types based on the schemas in relational databases, in current compilers, one would have to modify the compiler by hand. In general, consider a generic domain-specific language compilation framework, where a source file may refer to data governed by five different type systems: a Java system, and T2, T3, T4, T5 systems. The developer has a source file with different data types and specifies that data type A should satisfy the Java system rules, data type B should satisfy the T2 system rules, and so forth. What is desired is a general framework for developing compilers for such languages, such that a program can be checked with respect to the rules of the appropriate type systems.
Furthermore, when the compiler generates object code from the source programs, one would like to ensure that the appropriate type information is not lost. In some sense, the object code is also a domain-specific language, with its own set of types—it would be beneficial to extend it with auxiliary type systems using the same mechanisms as used for source programs.
There is a need for a method to retain type information of data belonging to different type systems in order to overcome the shortcomings of the prior art.